use crate::ws::AppState;
use axum::extract::{ConnectInfo, State};
use axum::http::HeaderMap;
use axum::response::IntoResponse;
use axum::routing::post;
use axum::{Json, Router};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use serde_json::json;
use void_log::log_info;
use crate::model::sys_user::SysUser;
use crate::model::sys_user_guild::SysUserGuild;
use crate::model::satori::{SatoriGuildMember, SatoriUser};

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriGuildMemberData {
    pub guild_id: Option<String>,    //群组 ID
    pub user_id: Option<String>,    //分页令牌
    pub next: Option<String>,    //请求 ID
    pub permanent: Option<bool>,    //是否通过请求
    pub duration: Option<i64>,    //禁言时长 (毫秒)
    pub approve: Option<bool>,    //是否通过请求
    pub comment: Option<String>,    //备注信息
}

async fn guild_member_get(State(app_state): State<AppState>,
                          headers: HeaderMap, ConnectInfo(addr): ConnectInfo<SocketAddr>,
                          Json(guild_data): Json<SatoriGuildMemberData>) -> impl IntoResponse {
    log_info!("{} | {:?}", addr.to_string(), headers);
    let user_id = guild_data.user_id.unwrap_or_default();
    let guild_id = guild_data.guild_id.unwrap_or_default();

    // 查询用户信息
    let user = SysUser::select_account_code(&app_state.pool, &user_id).await.unwrap_or_default();
    let satori_user = SatoriUser {
        id: user.account.unwrap().parse().unwrap(),
        ..Default::default()
    };

    // 查询用户在群组的信息
    let user_guild = SysUserGuild::select_user_guild_name(&app_state.pool, &user_id, &guild_id).await.unwrap_or_default();

    let joined_at = user_guild.get_joined_at_timestamp();

    // 组装并返回
    let satori_guild_member = SatoriGuildMember {
        user: Some(satori_user),
        nick: user_guild.nick,
        avatar: user_guild.avatar,
        joined_at,
    };
    Json(satori_guild_member)
}

async fn guild_member_list(State(app_state): State<AppState>,
                           headers: HeaderMap, ConnectInfo(addr): ConnectInfo<SocketAddr>,
                           Json(guild_data): Json<SatoriGuildMemberData>) -> impl IntoResponse {
    log_info!("{} | {:?}", addr.to_string(), headers);
    let guild_id = guild_data.guild_id.unwrap();
    let next = guild_data.next.unwrap();

    let mut data = vec![];

    // 查询用户在群组的信息
    let user_guilds = SysUserGuild::select_guild_name(&app_state.pool, &guild_id).await.unwrap();
    for user_guild in user_guilds {
        // 查询用户信息
        let satori_user = SatoriUser::select(&app_state.pool, &user_guild.user_id.unwrap()).await.unwrap();
        let joined_at = user_guild.get_joined_at_timestamp();

        // 组装并返回
        let satori_guild_member = SatoriGuildMember {
            user: Some(satori_user),
            nick: user_guild.nick,
            avatar: user_guild.avatar,
            joined_at,
        };
        data.push(satori_guild_member);
    }
    let res = json!({
        "data": data,
        "next": next
    });
    Json(res)
}

pub async fn router(app: Router<AppState>) -> Router<AppState> {
    app.route("/guild.member.get", post(guild_member_get))
        .route("/guild.member.list", post(guild_member_list))
}